package cn.muqingfeng.bbs.adapter;

import java.util.ArrayList;

import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import cn.muqingfeng.bbs.fragment.BaseFragment;

public class ViewPagerAdapter extends PagerAdapter {

	private ArrayList<PagerInfo> list = new ArrayList<PagerInfo>();
	private SparseArray<BaseFragment> mCachedFragments = new SparseArray<BaseFragment>();
	private Context context;

	private static final String TAG = "FragmentPagerAdapter";
	private static final boolean DEBUG = false;

	private final FragmentManager mFragmentManager;
	private FragmentTransaction mCurTransaction = null;
	private Fragment mCurrentPrimaryItem = null;

	public ViewPagerAdapter(FragmentManager fm, Context context) {
		super();
		mFragmentManager = fm;
		this.context = context;
	}

	@Override
	public int getCount() {
		return list.size();
	}

	public void onPause() {

	}

	@Override
	public CharSequence getPageTitle(int position) {
		return list.get(position).getTitle();
	}

	public BaseFragment getItem(int position) {
		PagerInfo info = list.get(position);
		int key = info.hashCode();
		BaseFragment fragment = mCachedFragments.get(key);
		if (fragment == null || fragment.isRemoving()) {
			fragment = (BaseFragment) Fragment.instantiate(context, info.getFragmentName(), info.getBundle());
			mCachedFragments.put(key, fragment);
		}
		return fragment;
	}

	public int getItemId(int position) {
		if (list.size() > position) {
			PagerInfo info = list.get(position);
			if (info != null) {
				return info.hashCode();
			}
		}
		return position;
	}

	@Override
	public void setPrimaryItem(ViewGroup container, int position, Object object) {
		super.setPrimaryItem(container, position, object);
		Fragment fragment = (Fragment) object;
		if (fragment != mCurrentPrimaryItem) {
			if (mCurrentPrimaryItem != null) {
				mCurrentPrimaryItem.setMenuVisibility(false);
				mCurrentPrimaryItem.setUserVisibleHint(false);
			}
			if (fragment != null) {
				fragment.setMenuVisibility(true);
				fragment.setUserVisibleHint(true);
			}
			mCurrentPrimaryItem = fragment;
		}
	}

	@Override
	public void startUpdate(ViewGroup container) {
	}

	@Override
	public Object instantiateItem(ViewGroup container, int position) {
		if (mCurTransaction == null) {
			mCurTransaction = mFragmentManager.beginTransaction();
		}

		final long itemId = getItemId(position);

		// Do we already have this fragment?
		String name = makeFragmentName(container.getId(), itemId);
		Fragment fragment = mFragmentManager.findFragmentByTag(name);
		if (fragment != null) {
			if (DEBUG)
				Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
			mCachedFragments.put((int) itemId, (BaseFragment) fragment);
			mCurTransaction.attach(fragment);
		} else {
			fragment = getItem(position);
			if (DEBUG)
				Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
			mCurTransaction.add(container.getId(), fragment, name);
		}
		if (fragment != mCurrentPrimaryItem) {
			fragment.setMenuVisibility(false);
			fragment.setUserVisibleHint(false);
		}

		return fragment;
	}

	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		if (mCurTransaction == null) {
			mCurTransaction = mFragmentManager.beginTransaction();
		}
		if (DEBUG)
			Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object + " v=" + ((Fragment) object).getView());
		int key = getItemId(position);
		mCachedFragments.remove(key);
		// mCurTransaction.remove( (Fragment)object);
		mCurTransaction.detach((Fragment) object);
	}

	@Override
	public void finishUpdate(ViewGroup container) {
		if (mCurTransaction != null) {
			mCurTransaction.commitAllowingStateLoss();
			mCurTransaction = null;
			mFragmentManager.executePendingTransactions();
		}
	}

	@Override
	public boolean isViewFromObject(View view, Object object) {
		return ((Fragment) object).getView() == view;
	}

	@Override
	public Parcelable saveState() {
		return null;
	}

	@Override
	public void restoreState(Parcelable state, ClassLoader loader) {
	}

	private static String makeFragmentName(int viewId, long id) {
		return "android:switcher:" + viewId + ":" + id;
	}

	public void setTitle(int pos, String title) {
		if (list.size() > pos) {
			PagerInfo info = list.get(pos);
			info.setTitle(title);
			list.set(pos, info);
		}
	}

	public void addPager(String title, String fragmentName, Bundle bundle) {
		PagerInfo info = new PagerInfo(title, fragmentName, bundle);
		list.add(info);
	}

	class PagerInfo {

		private String title;

		private String fragmentName;

		private Bundle bundle;

		private long initTime;

		public PagerInfo(String title, String fragmentName, Bundle bundle) {
			this.title = title;
			this.fragmentName = fragmentName;
			this.bundle = bundle;
			this.initTime = System.currentTimeMillis();
		}

		public void setTitle(String str) {
			this.title = str;
		}

		public String getTitle() {
			return title;
		}

		public String getFragmentName() {
			return fragmentName;
		}

		public Bundle getBundle() {
			return bundle;
		}

		public long getInitTime() {
			return initTime;
		}

	}

}
